package active

import (
	"server/game/cache"
	"server/share/config"
	"time"

	"github.com/hwcer/cosgo/registry"
	"github.com/hwcer/cosgo/utils"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
)

func init() {
	Register(&battlePass{})
}

//战令

type battlePass struct {
}

func (this *battlePass) Caller(node *registry.Node, handle *context.Context) interface{} {
	f := node.Method().(func(*battlePass, *context.Context) interface{})
	return f(this, handle)
}

// Submit 领取战令任务奖励
// id  int32 活动ID
// key int32 任务ID
func (this *battlePass) Submit(c *context.Context) any {
	id := c.GetInt32("id")
	key := c.GetInt32("key")
	if key <= 0 {
		return errors.ErrArgEmpty
	}
	ac := config.Data.Active[id]
	if ac == nil {
		return errors.ErrConfigEmpty
	}
	if ac.Mod != config.Data.ActiveMod.BattlePass {
		return c.Error("active config mod mismatched")
	}
	if len(ac.Args) < 2 {
		return c.Error("active config args empty")
	}
	rc := config.Data.BattlePassTask[key]
	if rc == nil {
		return errors.ErrConfigEmpty
	}
	if rc.Group != ac.Args[0] {
		return c.Error("Active key error")
	}

	handle := cache.GetActive(c.Player.Updater)
	item, cycle, err := handle.Verify(id)
	if err != nil {
		return err
	}
	attach := NewBattlePassModel()
	if err = item.Unmarshal(attach); err != nil {
		return err
	}
	if attach.Task == nil {
		attach.Task = make(map[int32]int64)
	}
	now := time.Now().Unix()
	if v, ok := attach.Task[key]; ok && v > now {
		return c.Error("active task exist")
	}
	if attach.Task[key], err = c.Player.Times.ExpireWithArray(rc.Expire...); err != nil {
		return err
	}
	//赛季任务
	if attach.Task[key] == 0 {
		if t, e := cycle.Expire(); e == nil {
			attach.Task[key] = t.Now().Unix()
		} else {
			attach.Task[key] = now + 360*86400
		}

	}

	week := attach.GetWeek()
	if v := ac.Args[1] - week.Score; v > 0 {
		mv := utils.Min(rc.Score, v)
		week.Score += mv
		attach.Exp += mv
		attach.Week = week
		//判断升级
		for {
			next := config.GetBattlePassLevel(rc.Group, attach.Lv+1)
			if next != nil && attach.Exp >= next.Exp {
				attach.Lv = next.Lv
				attach.Exp -= next.Exp
			} else {
				break
			}
		}
	}

	c.Player.Verify.Auto(Target(rc, cycle))
	c.Player.AddItems(rc.Item)
	handle.SetAttach(item.OID, attach)
	return nil
}

// Reward 领取战令等级奖励
// id  int32 活动ID
func (this *battlePass) Reward(c *context.Context) any {
	id := c.GetInt32("id")
	ac := config.Data.Active[id]
	if ac == nil {
		return errors.ErrConfigEmpty
	}
	if ac.Mod != config.Data.ActiveMod.BattlePass {
		return c.Error("active config mod mismatched")
	}
	if len(ac.Args) == 0 {
		return c.Error("active config args empty")
	}

	handle := cache.GetActive(c.Player.Updater)
	item, _, err := handle.Verify(id)
	if err != nil {
		return err
	}
	attach := NewBattlePassModel()
	if err = item.Unmarshal(attach); err != nil {
		return err
	}
	group := ac.Args[0]
	items := map[int32]int32{}
	//普通
	for i := attach.Free + 1; i <= attach.Lv; i++ {
		ki := group*10000 + i
		if cfg := config.Data.BattlePassReward[ki]; cfg != nil {
			attach.Free = cfg.Lv
			for _, v := range cfg.Item {
				if v.Id > 0 && v.Num > 0 {
					items[v.Id] += v.Num
				}
			}
		}
	}

	//高级
	if attach.Grade > 0 {
		for i := attach.Rare + 1; i <= attach.Lv; i++ {
			k := group*10000 + i
			if cfg := config.Data.BattlePassReward[k]; cfg != nil {
				attach.Rare = cfg.Lv
				for _, v := range cfg.Rare {
					if v.Id > 0 && v.Num > 0 {
						items[v.Id] += v.Num
					}
				}
			}
		}
	}
	if len(items) > 0 {
		for k, v := range items {
			c.Player.Add(k, v)
		}
		handle.SetAttach(item.OID, attach)
	}

	return nil
}

// Upgrade 升级，购买等级
// id  int32 活动ID
// num int32 购买次数，提升NUM 级
func (this *battlePass) Upgrade(c *context.Context) any {
	id := c.GetInt32("id")
	num := c.GetInt32("num")
	if num <= 0 {
		return errors.ErrArgEmpty
	}
	ac := config.Data.Active[id]
	if ac == nil {
		return errors.ErrConfigEmpty
	}
	if ac.Mod != config.Data.ActiveMod.BattlePass {
		return c.Errorf(0, "active config mod mismatched")
	}
	if len(ac.Args) == 0 {
		return c.Errorf(0, "active config args empty")
	}
	bp := config.Data.BattlePass[ac.Args[0]]
	if bp == nil {
		return c.Errorf(0, "BattlePass Not Found:%d", ac.Args[0])
	}
	if bp.PurchaseItem == 0 || bp.PurchaseNum == 0 {
		return c.Errorf(0, "BattlePass Can Not Buy:%d", ac.Args[0])
	}

	handle := cache.GetActive(c.Player.Updater)
	item, _, err := handle.Verify(id)
	if err != nil {
		return err
	}
	attach := NewBattlePassModel()
	if err = item.Unmarshal(attach); err != nil {
		return err
	}
	attach.Lv += num
	c.Player.Sub(bp.PurchaseItem, bp.PurchaseNum*num)
	handle.SetAttach(item.OID, attach)
	return nil
}
